package hd.util.load;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.widget.ImageView;

import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import hd.util.StringUtils;
import hd.util.file.FileUtil;

/**
 * listView图片缓存下载
 * <p/>
 * Created by haidy on 14/11/19.
 */
public class ImageLoader {

    private Cache<Bitmap> cache = new Cache<>();
    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    private Handler handler = new Handler();

    private OnImageCacheLoaderListener onImageCacheLoaderListener;


    private int imageRes;


    /**
     * 设置默认资源
     *
     * @param imageRes res
     */
    public void setImageRes(int imageRes) {
        this.imageRes = imageRes;
    }

    public synchronized void loadImage(String url, ImageView imageView, OnImageCacheLoaderListener onImageCacheLoaderListener) {
        this.onImageCacheLoaderListener = onImageCacheLoaderListener;
        if (onImageCacheLoaderListener != null) {
            executorService.submit(new LoaderRunnable(url, imageView));
        }
    }

    private class LoaderRunnable implements Runnable {

        private String url;
        private ImageView imageView;

        public LoaderRunnable(String url, ImageView imageView) {
            this.url = url;
            this.imageView = imageView;
        }

        /**
         * Starts executing the active part of the class' code. This method is
         * called when a thread is started that has been created with a class which
         * implements {@code Runnable}.
         */
        @Override
        public synchronized void run() {
            Bitmap bitmap = cache.get(url);
            if (bitmap == null && !StringUtils.isEmpty(url)) {//缓存为空就从网络获取
                String path = onImageCacheLoaderListener.onSDCardCache(url);
                if ((bitmap = FileUtil.loadBitmap(path)) == null) {//如果本地也不存在
                    try {//尝试从网络获取
                        bitmap = BitmapFactory.decodeStream(new URL(url).openStream());
                        if (bitmap != null) {
                            cache.add(url, bitmap);
                            FileUtil.saveBitmap(path, bitmap);
                        }
                    } catch (IOException e) {
                        bitmap = null;
                    }
                } else {//SDCard存在就存到缓存
                    cache.add(url, bitmap);
                }
            }
            handler.post(new BitmapRunnable(bitmap, imageView));
        }
    }


    private class BitmapRunnable implements Runnable {

        private Bitmap bitmap;
        private ImageView imageView;

        public BitmapRunnable(Bitmap bitmap, ImageView imageView) {
            this.bitmap = bitmap;
            this.imageView = imageView;
        }

        /**
         * Starts executing the active part of the class' code. This method is
         * called when a thread is started that has been created with a class which
         * implements {@code Runnable}.
         */
        @Override
        public synchronized void run() {
            if (imageView != null) {
                if (bitmap != null && !bitmap.isRecycled()) {
                    imageView.setImageBitmap(bitmap);
                } else {
                    imageView.setImageResource(imageRes);
                }
            }
        }
    }

    /**
     * 单个图片加载，不需要缓存到本地
     *
     * @param url      url
     * @param listener 回调接口
     */
    public static void setOnSingleImageLoaderListener(final String url, final OnSingleImageLoaderListener listener) {
        setOnSingleImageLoaderListener(url, null, listener);
    }

    /**
     * 单个图片加载
     *
     * @param url      url
     * @param savePath 缓存地址
     * @param listener 回调接口
     */
    public static void setOnSingleImageLoaderListener(final String url, final String savePath, final OnSingleImageLoaderListener listener) {
        BaseLoader.start(new BaseLoader.OnLoaderListener() {

            Bitmap bitmap;

            @Override
            public void load() {
                bitmap = FileUtil.loadBitmap(savePath);
                if (bitmap == null) {
                    try {
                        bitmap = BitmapFactory.decodeStream(new URL(url).openStream());
                        if (bitmap != null && savePath != null) {
                            FileUtil.saveBitmap(savePath, bitmap);
                        }
                    } catch (IOException ignored) {
                        bitmap = null;
                    }
                }
            }

            @Override
            public void finish() {
                listener.onLoaded(bitmap);
            }
        });
    }

    /**
     * 单独加载image
     */
    public interface OnSingleImageLoaderListener {
        void onLoaded(Bitmap bitmap);
    }

    /**
     * image 缓存接口
     */
    public interface OnImageCacheLoaderListener {

        /**
         * 从sdcard加载图片
         *
         * @param url url
         * @return image path
         */
        String onSDCardCache(String url);
    }

}